package com.wrb.gateway.filter;

import com.wrb.gateway.redis.RedisService;
import com.wrb.gateway.redis.keymodel.CustomerKey;
import com.wrb.gateway.utils.JWTUtils;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Arrays;
import java.util.LinkedHashSet;

@ConfigurationProperties("org.my.jwt")
@Component
@Data
public class LoginGlobalFilter implements GlobalFilter, Ordered {

	private String[] skipAuthUrls;

	public final static String ATTRIBUTE_IGNORE_TEST_GLOBAL_FILTER = "@ignoreLoginGlobalFilter";

	private static final String AUTHORIZE_TOKEN = "token";

	@Autowired
	private RedisService redisService;


	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		LinkedHashSet hashSet = exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR);
		URI gatewayUrl = (URI) hashSet.iterator().next();
		String url = gatewayUrl.getPath();
		//跳过不需要验证的路径
		if (null != skipAuthUrls && Arrays.asList(skipAuthUrls).contains(url)) {
			return chain.filter(exchange);
		} else {
			// 增加 jwt 校验，失败就返回401
			ServerHttpRequest request = exchange.getRequest();
			HttpHeaders headers = request.getHeaders();
			String token = headers.getFirst(AUTHORIZE_TOKEN);
			ServerHttpResponse response = exchange.getResponse();
			if (StringUtils.isNotBlank(token)) {
				String customerId = JWTUtils.checkToken(token);
				// 判断 jwt 解析出来的 customerId
				if (StringUtils.isBlank(customerId)) {
					response.setStatusCode(HttpStatus.UNAUTHORIZED);
					return response.setComplete();
				}
				String accessToken = redisService.get(CustomerKey.token, customerId, String.class);
				// 判断从 redis 获取的 accessToken 是否存在 及 跟请求传过来的 token 是否相同
				if (StringUtils.isBlank(accessToken) || !accessToken.equals(token)) {
					response.setStatusCode(HttpStatus.UNAUTHORIZED);
					return response.setComplete();
				}
				//向headers中放文件
				exchange.getRequest().mutate().header("customerId", new String[]{customerId}).build();
			} else {
				response.setStatusCode(HttpStatus.UNAUTHORIZED);
				return response.setComplete();
			}
			return chain.filter(exchange);
		}
	}

	@Override
	public int getOrder() {
		//在GatewayFilter之后执行
		return 10;
	}
}